package com.mini.mybatis.binding;

import com.mini.mybatis.session.SqlSession;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 映射器代理工厂 - 创建Mapper接口的代理实例
 */
public class MapperProxyFactory<T> {
    
    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<>();
    
    public MapperProxyFactory(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }
    
    public Class<T> getMapperInterface() {
        return mapperInterface;
    }
    
    public Map<Method, MapperMethod> getMethodCache() {
        return methodCache;
    }
    
    /**
     * 创建映射器代理实例
     * @param sqlSession SQL会话
     * @return 代理实例
     */
    @SuppressWarnings("unchecked")
    public T newInstance(SqlSession sqlSession) {
        final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
    }
    
    /**
     * 创建代理实例
     * @param mapperProxy 映射器代理对象
     * @return 代理实例
     */
    @SuppressWarnings("unchecked")
    protected T newInstance(MapperProxy<T> mapperProxy) {
        return (T) Proxy.newProxyInstance(
            mapperInterface.getClassLoader(),
            new Class[]{mapperInterface},
            mapperProxy
        );
    }
}